package mge.ui 
{
  import flash.events.Event;
  import flash.events.TimerEvent;
  import flash.text.TextField;
  import flash.utils.Timer;
  import mge.StringUtils;
  
  
	/**
   * ...
   * @author ivan
   */
  public class TextTyped 
  {
      //private var parent:DisplayObjectContainer;
      private var text:String;
      private var textLength:int;
      private var textField:TextField;
      private var currentCharacter:int;
      private var timer:Timer;
      private var end:Function;
    
    public function TextTyped(textField:TextField) 
    {
        this.text = text;
        this.textField = textField;
        
        textField.htmlText = "";      
    }
    
    public function type(text:String, end:Function = null):void
    {
      this.end = end;
      this.text = text;
      currentCharacter = 0;
      
      textLength = StringUtils.stripTags(text).length;
      
      timer = new Timer(25);
      timer.removeEventListener(TimerEvent.TIMER, onTimer);
      timer.addEventListener(TimerEvent.TIMER, onTimer);
      timer.start();
      
      _typing = true;
      
      onTimer(null);
    }
    
    private function onTimer(e:Event):void
    {
        currentCharacter++;
        
        if (currentCharacter >= textLength)
        {
          timer.removeEventListener(TimerEvent.TIMER, onTimer);
          _typing = false;
          if (end != null) end();
        }
        
        var t:String = StringUtils.substrHtml(text, currentCharacter);
        
        
        // Find the end of the current word
        // Call last character written n
        // 
        var textWithLastWord:String = StringUtils.stripTags(text);
        var nextSpaceIdx:int = textWithLastWord.indexOf(" ", currentCharacter);
        if (nextSpaceIdx == -1)
          nextSpaceIdx = textWithLastWord.length - 1;
        
        var last_token:String = StringUtils.substrHtml(text, nextSpaceIdx);
        
        textField.htmlText = last_token;
        var nextWordLines:int = textField.numLines;
        
        textField.htmlText = t;
        var currentLines:int = textField.numLines;
        
        if (nextWordLines != currentLines)
        {
          // If current word will be broke i another line, a <br/> is inserted before last word.
          // The algorith to do that:
          // Start at last element, call it n.
          // While (1) {
          //   If n == '>' mark tag opened
          //   If n == '<' mark tag closed
          //   If n == ' ' && tag closed, then that's where the last word ends.
          //   n--
          // }
          // If last word found, find ' ' before word and insert there an '<br/>' tag.
          var idx:int = t.length -1;
          
          var tagOpened:Boolean = false;
          while (true)
          {
            if (idx <= 0)
              break;
              
            var n:String = t.charAt(idx);
            if (n == '>') tagOpened = true;
            if (n == '<') tagOpened = false;
            if (n == ' ' && !tagOpened)
            {
              t = StringUtils.insert(t, "<br />", idx + 1);
              textField.htmlText = t;
              break;
            }
            idx--;
          }
        }
    }
    
    // Writes all inmeditely
    public function typeInstant():void
    {
      currentCharacter = textLength;
      textField.htmlText = text;
    }
    
    public function get typing():Boolean { return _typing; }
    
    private var _typing:Boolean;
    
  }

}